package fr.grobim.hangovers.gestionBudget.actions.factures;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.ResultPath;
import org.apache.struts2.interceptor.validation.SkipValidation;
import org.springframework.beans.factory.annotation.Autowired;

import fr.grobim.hangovers.gestionBudget.actions.champs.factures.ReglementFactureChamps;
import fr.grobim.hangovers.gestionBudget.actions.enums.AttributsSession;
import fr.grobim.hangovers.gestionBudget.actions.support.AbstractActionSupport;
import fr.grobim.hangovers.gestionBudget.actions.utils.ComboBoxUtils;
import fr.grobim.hangovers.gestionBudget.beans.comptes.Membre;
import fr.grobim.hangovers.gestionBudget.beans.factures.ReglementFacture;
import fr.grobim.hangovers.gestionBudget.services.comptes.MembreService;
import fr.grobim.hangovers.gestionBudget.services.factures.FacturationService;

@Namespace(value = "/")
@ResultPath(value = "/")
public class GestionReglementFactureAction extends AbstractActionSupport {

	private static final long serialVersionUID = 1L;

	@Autowired
	private MembreService membreService;

	@Autowired
	private FacturationService facturationService;

	private Integer idGestionGeree;

	private ReglementFactureChamps reglementFactureAjout;

	private Integer idReglementSelectionne;

	private ReglementFactureChamps reglementFactureModif;

	private Map<Integer, String> mapPayeur;

	private Map<Integer, String> mapMembresConcernes;

	@Action(value = "chargerReglementFacture", results = { @Result(location = "facture.gererReglement.detail", type = "tiles") })
	public String chargerReglementFacture() throws Exception {
		getSession().put(AttributsSession.GESTION_REGLEMENT_ID_FACTURE.getClee(), this.idGestionGeree);
		this.chargerPanelAjout(this.idGestionGeree);
		return SUCCESS;
	}

	@Action(value = "ajouterReglementFacture", results = { @Result(location = "facture.gererReglement.detail", type = "tiles") })
	@SkipValidation
	public String ajouterReglementFacture() {
		ReglementFacture nouveauReglement = new ReglementFacture();
		nouveauReglement.setDatePayement(this.reglementFactureAjout.getDateReglement());
		nouveauReglement.setFacture(this.facturationService.obtenirFacture(this.reglementFactureAjout.getFactureId()));
		nouveauReglement.setPrix(NumberUtils.createDouble(StringUtils.defaultIfBlank(
				StringUtils.replace(this.reglementFactureAjout.getMontant(), ",", "."), null)));
		nouveauReglement.setPayeur(new Membre(this.reglementFactureAjout.getIdPayeur()));

		if (StringUtils.isNotEmpty(this.reglementFactureAjout.getMembresSelectionnes())) {
			String[] membresIdsSelectionnes = StringUtils.split(this.reglementFactureAjout.getMembresSelectionnes(),
					", ");
			Set<Membre> membresSelectionnes = new HashSet<Membre>(membresIdsSelectionnes.length);
			for (String membreIdSelectinne : membresIdsSelectionnes) {
				membresSelectionnes.add(this.membreService.obtenirMembre(Integer.valueOf(membreIdSelectinne)));
			}
			nouveauReglement.setMembreConcernes(membresSelectionnes);
		}
		this.facturationService.reglerFacture(nouveauReglement);
		this.chargerPanelAjout(this.reglementFactureAjout.getFactureId());
		return SUCCESS;
	}

	@Action(value = "afficherDetailReglement", results = { @Result(location = "facture.gererReglement.detail", type = "tiles") })
	public String afficherDetailReglement() throws Exception {
		Integer idFacture = this.getObjectDeSession(AttributsSession.GESTION_REGLEMENT_ID_FACTURE);
		this.chargerPanelAjout(idFacture);
		this.chargerPanelModif();
		return SUCCESS;
	}

	@Action(value = "modifierReglement", results = { @Result(location = "facture.gererReglement.detail", type = "tiles") })
	@SkipValidation
	public String modifierReglement() {
		ReglementFacture reglementEnBase = this.facturationService.obtenirReglement(this.idReglementSelectionne);
		boolean difference = false;

		Double prixEnBase = reglementEnBase.getPrix();
		Double prixSaisi = NumberUtils.createDouble(StringUtils.defaultIfBlank(
				StringUtils.replace(this.reglementFactureModif.getMontant(), ",", "."), null));
		
		if (!prixEnBase.equals(prixSaisi)) {
			reglementEnBase.setPrix(prixSaisi);
			difference = true;
		}
		
		if (!reglementEnBase.getPayeur().getId().equals(this.reglementFactureModif.getIdPayeur())) {
			reglementEnBase.setPayeur(new Membre(this.reglementFactureModif.getIdPayeur()));
			difference = true;
		}
		
		if (!reglementEnBase.getDatePayement().equals(this.reglementFactureModif.getDateReglement())) {
			reglementEnBase.setDatePayement(this.reglementFactureModif.getDateReglement());
			difference = true;
		}
		
		String[] idsMembresSelectionnes = StringUtils.split(this.reglementFactureModif.getMembresSelectionnes(), ", ");
		Set<Integer> idsMembres = new TreeSet<Integer>();
		for (String idMembre : idsMembresSelectionnes) {
			idsMembres.add(Integer.valueOf(idMembre));
		}
		boolean diffMembresConcernes = false;
		
		if (idsMembresSelectionnes.length != reglementEnBase.getMembreConcernes().size()) {
			diffMembresConcernes = true;
		} else {
			for (Membre membreEnBase : reglementEnBase.getMembreConcernes()) {
				if (!idsMembres.contains(membreEnBase.getId())) {
					diffMembresConcernes = true;
					break;
				}
			}
		}

		if (diffMembresConcernes) {
			reglementEnBase.getMembreConcernes().clear();
			for (Integer idMembre : idsMembres) {
				reglementEnBase.getMembreConcernes().add(this.membreService.obtenirMembre(idMembre));
			}
			difference = true;
		}
		
		if (difference) {
			this.facturationService.ajouterOuModifierReglement(reglementEnBase);
			this.addActionMessage(this.getText("facture.reglements.modifierReglement.confirmation"));
			this.idReglementSelectionne = null;
		} else {
			this.addActionError(this.getText("facture.reglements.modifierReglement.erreur.pasDeModification"));
			this.chargerPanelModif();
		}
		this.chargerPanelAjout(reglementEnBase.getFacture().getId());
		return SUCCESS;
	}

	@Action(value = "supprimerReglement", results = { @Result(location = "facture.gererReglement.detail", type = "tiles") })
	public String supprimerReglement() {
		Integer idFacture = this.getObjectDeSession(AttributsSession.GESTION_REGLEMENT_ID_FACTURE);
		this.facturationService.supprimerReglementFacture(this.idReglementSelectionne);
		addActionMessage(getText("facture.reglements.supprimerReglement.confirmation"));
		this.idReglementSelectionne = null;
		this.chargerPanelAjout(idFacture);
		return SUCCESS;
	}

	private void chargerPanelAjout(Integer _idFacture) {
		List<Membre> listeTousMembres = this.membreService.listerTousMembresInternes();
		this.mapPayeur = ComboBoxUtils.creerMapMembre(listeTousMembres);
		this.mapMembresConcernes = ComboBoxUtils.creerMapMembre(listeTousMembres);
		if (_idFacture != null) {
			this.reglementFactureAjout = new ReglementFactureChamps(this.facturationService.obtenirFacture(_idFacture));
			this.idGestionGeree = _idFacture;
		}
	}

	private void chargerPanelModif() {
		this.reglementFactureModif = new ReglementFactureChamps(
				this.facturationService.obtenirReglement(this.idReglementSelectionne));
	}

	public Integer getIdGestionGeree() {
		return idGestionGeree;
	}

	public void setIdGestionGeree(Integer idGestionGeree) {
		this.idGestionGeree = idGestionGeree;
	}

	public ReglementFactureChamps getReglementFactureAjout() {
		return reglementFactureAjout;
	}

	public void setReglementFactureAjout(ReglementFactureChamps reglementFactureAjout) {
		this.reglementFactureAjout = reglementFactureAjout;
	}

	public Integer getIdReglementSelectionne() {
		return idReglementSelectionne;
	}

	public void setIdReglementSelectionne(Integer idReglementSelectionne) {
		this.idReglementSelectionne = idReglementSelectionne;
	}

	public ReglementFactureChamps getReglementFactureModif() {
		return reglementFactureModif;
	}

	public void setReglementFactureModif(ReglementFactureChamps reglementFactureModif) {
		this.reglementFactureModif = reglementFactureModif;
	}

	public Map<Integer, String> getMapPayeur() {
		return mapPayeur;
	}

	public void setMapPayeur(Map<Integer, String> mapPayeur) {
		this.mapPayeur = mapPayeur;
	}

	public Map<Integer, String> getMapMembresConcernes() {
		return mapMembresConcernes;
	}

	public void setMapMembresConcernes(Map<Integer, String> mapMembresConcernes) {
		this.mapMembresConcernes = mapMembresConcernes;
	}

}
